<div class="p-4 bg-white border border-gray-200 rounded-lg shadow-sm dark:border-gray-700 sm:p-6 dark:bg-gray-800">
    <div class="flex items-center justify-between mb-4">
        <h3 class="text-lg font-semibold text-gray-900 dark:text-white">Total active users</h3>
    </div>
    @if (IsLoading)
    {
        <LoadingIndicator />
    }
    else
    {
        <div class="grid grid-cols-2 lg:grid-cols-4 gap-4">
            <div class="bg-green-50 dark:bg-green-900/30 p-4 rounded-lg cursor-pointer hover:bg-green-100 dark:hover:bg-green-900/40 transition-colors" @onclick="NavigateToUsers">
                <p class="text-sm font-medium text-gray-500 dark:text-gray-400">Last 24 hours</p>
                <div class="flex items-baseline gap-2">
                    <h4 class="text-2xl font-bold text-gray-900 dark:text-white">@UserStats.Last24Hours</h4>
                    <span class="text-sm text-gray-600 dark:text-gray-400" title="Returning users">(@UserStats.ReturningLast24Hours)</span>
                </div>
            </div>
            <div class="bg-green-50 dark:bg-green-900/30 p-4 rounded-lg cursor-pointer hover:bg-green-100 dark:hover:bg-green-900/40 transition-colors" @onclick="NavigateToUsers">
                <p class="text-sm font-medium text-gray-500 dark:text-gray-400">Last 3 days</p>
                <div class="flex items-baseline gap-2">
                    <h4 class="text-2xl font-bold text-gray-900 dark:text-white">@UserStats.Last3Days</h4>
                    <span class="text-sm text-gray-600 dark:text-gray-400" title="Returning users">(@UserStats.ReturningLast3Days)</span>
                </div>
            </div>
            <div class="bg-green-50 dark:bg-green-900/30 p-4 rounded-lg cursor-pointer hover:bg-green-100 dark:hover:bg-green-900/40 transition-colors" @onclick="NavigateToUsers">
                <p class="text-sm font-medium text-gray-500 dark:text-gray-400">Last 7 days</p>
                <div class="flex items-baseline gap-2">
                    <h4 class="text-2xl font-bold text-gray-900 dark:text-white">@UserStats.Last7Days</h4>
                    <span class="text-sm text-gray-600 dark:text-gray-400" title="Returning users">(@UserStats.ReturningLast7Days)</span>
                </div>
            </div>
            <div class="bg-green-50 dark:bg-green-900/30 p-4 rounded-lg cursor-pointer hover:bg-green-100 dark:hover:bg-green-900/40 transition-colors" @onclick="NavigateToUsers">
                <p class="text-sm font-medium text-gray-500 dark:text-gray-400">Last 30 days</p>
                <div class="flex items-baseline gap-2">
                    <h4 class="text-2xl font-bold text-gray-900 dark:text-white">@UserStats.Last30Days</h4>
                    <span class="text-sm text-gray-600 dark:text-gray-400" title="Returning users (activity 24h after registration)">(@UserStats.ReturningLast30Days)</span>
                </div>
            </div>
        </div>
    }
</div>

@inject NavigationManager NavigationManager

@code {
    private bool IsLoading { get; set; } = true;
    private UserStatistics UserStats { get; set; } = new();

    /// <summary>
    /// Refreshes the data displayed on the card.
    /// </summary>
    public async Task RefreshData()
    {
        IsLoading = true;
        StateHasChanged();

        var now = DateTime.UtcNow;
        var last24Hours = now.AddHours(-24);
        var last3Days = now.AddDays(-3);
        var last7Days = now.AddDays(-7);
        var last30Days = now.AddDays(-30);

        // Get user statistics
        var (count24h, returning24h) = await GetActiveUserCount(last24Hours);
        var (count3d, returning3d) = await GetActiveUserCount(last3Days);
        var (count7d, returning7d) = await GetActiveUserCount(last7Days);
        var (count30d, returning30d) = await GetActiveUserCount(last30Days);

        UserStats = new UserStatistics
        {
            Last24Hours = count24h,
            Last3Days = count3d,
            Last7Days = count7d,
            Last30Days = count30d,
            ReturningLast24Hours = returning24h,
            ReturningLast3Days = returning3d,
            ReturningLast7Days = returning7d,
            ReturningLast30Days = returning30d,
        };

        IsLoading = false;
        StateHasChanged();
    }

    private async Task<(int totalCount, int returningCount)> GetActiveUserCount(DateTime since)
    {
        await using var dbContext = await DbContextFactory.CreateDbContextAsync();

        // Get all active users for the period
        var activeUsers = await dbContext.AuthLogs
            .Where(l => l.Timestamp >= since && l.IsSuccess && l.Username != "admin")
            .Select(l => l.Username)
            .Distinct()
            .ToListAsync();

        // Get returning users (those who have activity at least 24h after registration
        var returningUsers = await dbContext.AuthLogs
            .Where(l => l.Timestamp >= since && l.IsSuccess && l.Username != "admin")
            .Join(
                dbContext.AliasVaultUsers,
                log => log.Username,
                user => user.UserName,
                (log, user) => new { log, user }
            )
            .Where(x => x.log.Timestamp >= x.user.CreatedAt.AddHours(24))
            .Select(x => x.log.Username)
            .Distinct()
            .ToListAsync();

        return (activeUsers.Count, returningUsers.Count);
    }

    private sealed class UserStatistics
    {
        public int Last24Hours { get; set; }
        public int Last3Days { get; set; }
        public int Last7Days { get; set; }
        public int Last30Days { get; set; }
        public int ReturningLast24Hours { get; set; }
        public int ReturningLast3Days { get; set; }
        public int ReturningLast7Days { get; set; }
        public int ReturningLast30Days { get; set; }
    }

    private void NavigateToUsers()
    {
        NavigationManager.NavigateTo("users");
    }
}
